#pragma once

#include "stdafx.h"
#include "stdlib.h"
#include <vector>
#include <string>
#include "..\\Converter\\Converter.h"
using namespace Converter;

using namespace System;
using namespace System::Windows::Forms;
using namespace System::Runtime::InteropServices;


//
// RGBA
//

union TRGBA
{
	uint32	uRGBA;
	uint8	aRGBA[4];
	///
	TRGBA(): uRGBA(0) {}
	TRGBA(uint32 uValue): uRGBA(uValue) {}
	TRGBA(uint8 rgba[4]) { memcpy(aRGBA, rgba, sizeof(aRGBA)); }

	uint8 & R()			{ return aRGBA[3]; }
	uint8 & G()			{ return aRGBA[2]; }
	uint8 & B()			{ return aRGBA[1]; }
	uint8 & A()			{ return aRGBA[0]; }

	uint8   R()	const	{ return aRGBA[3]; }
	uint8   G()	const	{ return aRGBA[2]; }
	uint8   B()	const	{ return aRGBA[1]; }
	uint8   A()	const	{ return aRGBA[0]; }

	TRGBA & operator = (const uint right)
	{
		uRGBA = right;
		return *this;
	}
};


//
// ARGB
//

union TARGB
{
	uint32	uARGB;
	uint8	aARGB[4];
	///
	TARGB(): uARGB(0) {}
	TARGB(uint32 uValue): uARGB(uValue) {}
	TARGB(uint8 argb[4]) { memcpy(aARGB, argb, sizeof(aARGB)); }
	TARGB(const TRGBA &rgba) { *this = rgba; }

	uint8 & R()			{ return aARGB[2]; }
	uint8 & G()			{ return aARGB[1]; }
	uint8 & B()			{ return aARGB[0]; }
	uint8 & A()			{ return aARGB[3]; }

	uint8   R()	const	{ return aARGB[2]; }
	uint8   G()	const	{ return aARGB[1]; }
	uint8   B()	const	{ return aARGB[0]; }
	uint8   A()	const	{ return aARGB[3]; }

	operator TRGBA ()
	{
		TRGBA	rgba;
		rgba.R() = R();
		rgba.G() = G();
		rgba.B() = B();
		rgba.A() = A();
		return rgba;
	}

	TARGB & operator = (const TRGBA &right)
	{
		R() = right.R();
		G() = right.G();
		B() = right.B();
		A() = right.A();
		return *this;
	}

	TARGB & operator = (const uint right)
	{
		uARGB = right;
		return *this;
	}
};


//
// Converter Wrapper
//

class CConvWrapper
{
private:
	IConverter			*	_pConverter;
	ITextureConverter	*	_pTexture;
	IFontConverter		*	_pFont;
	ISpriteConverter	*	_pSprite;
	IModelConverter		*	_pModel;
	ISoundConverter		*	_pSound;
	IVideoConverter		*	_pVideo;
	ITerrainConverter	*	_pTerrain;

	// texture //
	uint		_uLayer,
				_uMipmap;
	bool		_bMipmapList,	// or Layers list
				_bTexLoaded;
	std::string	_sTexName;

	// sprite //
	std::string	_sSpriteName;
	uint		_uSprNumb,
				_uAnimNumb;

	std::vector< TSpriteFrame >
				_aFrames;

	// font //
	std::string	_sFontName;

	// model //
	struct TAttrib
	{
		TMeshVertices	sVert;
		std::string		sText;
	};

	std::vector< TAttrib >
						_aAttribs;
	E_MODEL_COMPONENT	_eSelectedGroup;
	uint				_uSelected;

	// sound //
	std::string	_sSoundName;

	bool		_bIsInited;

private:
	const char * GetAttribName(E_VERTEX_ATTRIBUTE eAttrib);
	const char * GetValueName(E_VERTEX_VALUE_TYPE eValue);

public:
	CConvWrapper();
	~CConvWrapper();

	bool IsInited()				const	{ return _bIsInited; }
	
	bool GetVersion(String ^&pStr);
	bool GetErrors(ListBox ^pList, bool &bNewErrors);


	// Utils //
	int  StrToInt(String ^pStr);
	int  StrToInt16(String ^pStr);
	void IntToStr(int iValue, String ^&pStr, int iRadix);

	float StrToFloat(String ^pStr);
	void  FloatToStr(float fValue, String ^&pStr);


	// Texture //
	bool GetSupportedTextureFormats(String ^&pStr);
	bool GetMainTextureName(String ^&pStr);

	void GetTextureInternalFormatsList(ComboBox ^pComboBox);
	void GetTextureColorFormatsList(ComboBox ^pComboBox);
	void GetTextureColorValueTypesList(ComboBox ^pComboBox);

	bool IsTextureLoaded()		const		{ return _bTexLoaded; }
	bool IsMipmapListSelected()	const		{ return _bMipmapList; }
	bool IsLayerListSelected()	const		{ return !_bMipmapList; }

	bool CreateTexture(E_TEXTURE_TYPE eType);
	bool DeleteTexture();
	bool LoadTexture(String ^pStr);
	bool SaveTexture(String ^pStr);

	void SelectTexture(uint uNumb);
	void SelectTextureMode(bool bMipmaps);

	bool AddTexture(String ^pStr);
	bool RemoveTexture();
	bool UpTextureLayer();
	bool DownTextureLayer();

	bool GetTextureName(String ^&pStr);
	void GetTextureNames(ListBox ^pList);
	bool GetTextureInfo(String ^&pStr);
	bool GetTextureFormat(TTextureFormat &sFormat);
	bool SetTextureFormat(const TTextureFormat &sFormat);


	// Model //
	bool GetSupportedModelFormats(String ^&pStr);
	void GetVertexAttribsList(ComboBox ^pCombo);
	void GetVertexValuesList(ComboBox ^pCombo);

	bool DeleteModel();
	bool LoadModel(String ^pStr, E_MODEL_COMPONENT eComp);
	bool SaveModel(String ^pStr, E_MODEL_COMPONENT eComp);

	void MergeModelComponents(E_MODEL_COMPONENT eType);
	void RemoveModelComponent(E_MODEL_COMPONENT eType, uint uIndex);
	void GetModelComponentsNames(ListBox ^pList, E_MODEL_COMPONENT eComp);

	bool GetModelType(E_MODEL_TYPE &eType);
	bool SetModelType(E_MODEL_TYPE eType);

	bool SetModelOptimizeParams(uint uCashSize, float fAccuracy, E_MESH_FLAGS eFlags, E_MESH_VERT_PACK ePackType);
	bool GetModelOptimizeParams(uint &uCashSize, float &fAccuracy, E_MESH_FLAGS &eFlags, E_MESH_VERT_PACK &ePackType);

	void SelectModelComponent(E_MODEL_COMPONENT eComp, uint uIndex);
	
	bool UpdateMeshAttribs();
	bool SetMeshAttribs();

	void GetMeshAttribs(ListBox ^pList);
	bool AddMeshAttrib(uint uAttrib, uint uValue, float fScale, bool bNormalize, bool bNormalized, bool bScale, uint uIndex = -1);
	bool RemoveMeshAttrib(uint uIndex);

	void ApplyMeshChanges();


	// Font //
	bool GetSupportedFontFormats(String ^&pStr);
	bool GetFontName(String ^&pStr);

	bool CreateFont();
	bool DeleteFont();

	bool LoadFont(String ^pStr);
	bool SaveFont(String ^pStr);

	bool SetFontOffsets(uint uASCII, uint uUnicode);
	bool GetFontOffsets(uint &uASCII, uint &uUnicode);
	bool SetFontCharsCount(uint uCount);
	bool GetFontCharsCount(uint &uCount);


	// Sprite //
	bool GetSupportedSpriteFormats(String ^&pStr);
	bool GetSpriteName(String ^&pStr);

	bool CreateSprite();
	bool DeleteSprite();
	bool BuildSprite();
	bool SaveSprite(String ^pStr);

	void SelectSprite(uint uNumb);
	void SelectAnimation(uint uAnim);

	uint GetSelectedSprite()	const	{ return _uSprNumb; }
	uint GetSelectedAnimation()	const	{ return _uAnimNumb; }

	bool AddSpriteTexture(String ^pStr);
	bool RemoveSpriteTexture();
	bool GetSpriteTextureInfo(String ^&pStr);
	bool GetSpriteNames(ListBox ^pList);
	bool SetSpriteFrame(uint x, uint y);
	bool GetSpriteFrame(uint &x, uint &y);

	bool AddSpriteFrame(uint uIndex, uint uARGB);
	bool GetSpriteFrame(uint uNumb, uint &uIndex, uint &uARGB);
	bool RemoveSpriteFrame(uint uNumb);
	bool MoveUpSpriteFrame(uint uNumb);
	bool MoveDownSpriteFrame(uint uNumb);
	bool GetSpriteFrames(ListBox ^pList);
	bool ClearSpriteFrames();

	bool AddSpriteAnimation(String ^pName, float fFrameRate);
	bool RemoveSpriteAnimation();
	bool GetSpriteAnimationNames(ComboBox ^pComboBox);
	bool GetSpriteAnimation(String ^&pName, ListBox ^pFrames, float &fFrameRate);
	bool ChangeSpriteAnimation(String ^pName, float fFrameRate);
	bool GetSpriteInfo(String ^&pStr);

	bool GetSpriteFormat(TTextureFormat &sFormat);
	bool SetSpriteFormat(const TTextureFormat &sFormat);
	bool GetSpriteParams(TSpriteParams &sParams);
	bool SetSpriteParams(const TSpriteParams &sParams);


	// Sound //
	bool GetSupportedSoundFormats(String ^&pStr);
	bool GetSoundName(String ^&pStr);

	bool DeleteSound();
	bool LoadSound(String ^pStr);
	bool SaveSound(String ^pStr);

	bool SetSoundParams(const TSoundParams &sParams);
	bool GetSoundParams(TSoundParams &sParams);
	bool GetSoundInfo(String ^&pStr);


	// Video //

	// Terrain //
};